package android.demo.engine;

import android.content.Intent;
import android.demo.engine.tasks.ActivityTask;
import android.demo.engine.tasks.Task;
import android.demo.engine.visitor.BackHandlerVisitor;
import android.demo.engine.visitor.ProcessingVisitor;
import android.os.Bundle;

/**
 * @author  carlo
 */
public class BusinessProcess{
	/**
	 * @uml.property  name="mState"
	 * @uml.associationEnd  
	 */
	private ProcessStateManager mState;
	/**
	 * @uml.property  name="mTasks"
	 * @uml.associationEnd  
	 */
	private TaskGraph mTasks;
	/**
	 * @uml.property  name="mProcVisitor"
	 * @uml.associationEnd  
	 */
	private ProcessingVisitor mProcVisitor;
	/**
	 * @uml.property  name="mRootActivity"
	 * @uml.associationEnd  
	 */
	private RootActivity mRootActivity;
	
	private PendingTaskManager mPendingTaskManager;
	
	public BusinessProcess(Bundle savedInstanceState,RootActivity rootActivity){
		this.mRootActivity= rootActivity;
		this.mState= new ProcessStateManager(savedInstanceState);
		this.mProcVisitor= new ProcessingVisitor(this);
		this.mPendingTaskManager= new PendingTaskManager(this);
		this.mTasks= new TaskGraph();
		rootActivity.addListener(new EventHandler());
	}
	public void saveState(Bundle outState) {
		mState.saveState(outState);
	}

	public void exec() {
		Task task = mTasks.getTask(mState.getCurrentTaskId());
			Task toWait= task.hasToWait();
			if(toWait!=null){
				mRootActivity.showToast("task "+task.getId() +" is waiting "+toWait.getId());
				mPendingTaskManager.addTask(toWait, task);
			}else{
				
				if(task.isExecuted())
					execNext(task);
				else
					task.accept(mProcVisitor);
			}
	}
	public void execNext(Task task) {
		Task next= mTasks.getNextTask(task);
		execTask(next);
		
	}
	public void execTask(Task task){
		if(task==null)
			mRootActivity.finish();
		else{
			mState.setCurrentTaskId(task.getId());
			exec();
		}
	}
	
	public ProcessStateManager getState() {
		return mState;
	}

	public TaskGraph getTasks() {
		return mTasks;
	}
	public PendingTaskManager getPendingTaskManager() {
		return mPendingTaskManager;
	}
		
	public RootActivity getRootActivity() {
		return mRootActivity;
	}

	public void goBackToPreviousActivity(Task current) {
		BackHandlerVisitor visitor = new BackHandlerVisitor(this);
		current.accept(visitor);
		execTask(visitor.getResult());
	}
	
	private class EventHandler implements ActivityListener{
		@Override
		public void onActivityResult(int taskId, Intent data) {
			ActivityTask task;
			task= (ActivityTask) mTasks.getTask(taskId); //it must be an ActivityTask!
			task.manageResult(data, mState); //handle received data
			execNext(task);
		}
		@Override
		public void onBackRequest(int taskId) {
			ActivityTask currentTask= (ActivityTask)mTasks.getTask(taskId);
			if(currentTask.hasResult())
				goBackToPreviousActivity(currentTask);
			else
				execNext(currentTask);
		}
	}

	public boolean isCurrentTask(Task task) {
		return task.getId()==mState.getCurrentTaskId();
	}
}
